const jwt = require("jsonwebtoken");

const errorType = require("../constants/error-types");
const userService = require("../service/user.service");
const authService = require("../service/auth.service");
const md5password = require("../utils/password-handle.js");

const { PUBLIC_KEY } = require("../app/config");
const verifyLogin = async (ctx, next) => {
  const { name, password } = ctx.request.body;
  //1.判断用户名密码是否为空
  if (!name || !password || name === "" || password === "") {
    const error = new Error(errorType.NAME_OR_PASSWORD_IS_REQUIRED);
    return ctx.app.emit("error", error, ctx);
  }
  //2.判断登录时的用户名存不存在
  const result = await userService.getUserByName(name);
  const user = result[0];
  //   console.log(result);
  //   console.log(user);
  /**
    *  console.log(user):
    * BinaryRow {
             id: 5,
             name: 'gl',
             password: 'e10adc3949ba59abbe56e057f20f883e',
             createAt: 2021-02-19T05:51:23.000Z,
             updateAt: 2021-02-19T05:51:23.000Z
           }
    */
  if (!user) {
    const error = new Error(errorType.USER_DOES_NOT_EXISTS);
    return ctx.app.emit("error", error, ctx);
  }
  //3.判断密码是否正确(加密)
  //把用户输入的密码加密后与数据库中取的值进行比对
  if (md5password(password) !== user.password) {
    const error = new Error(errorType.PASSWORD_IS_INCORRENT);
    return ctx.app.emit("error", error, ctx);
  }

  // 给ctx一个user属性
  ctx.user = user;
  //如果都没有错就往下执行
  await next();
};
const verifyAuth = async (ctx, next) => {
  console.log("验证授权的middleware");
  // 1.解析出token
  const authorization = ctx.headers.authorization;
  // 判断有没有authorization
  if (!authorization) {
    const error = new Error(errorType.UNAUTHORIZATION);
    return ctx.app.emit("error", error, ctx);
  }
  const token = authorization.replace("Bearer ", "");
  // 2.jwt验证token令牌，try{}catch(){}捕获错误
  try {
    const result = jwt.verify(token, PUBLIC_KEY, {
      algorithms: ["RS256"],
    });
    ctx.user = result;

    await next();
  } catch (err) {
    // 捕获到错误后返回给客户端
    const error = new Error(errorType.UNAUTHORIZATION);
    ctx.app.emit("error", error, ctx);
  }
};

/**
 * 1.很多的内容都需要验证权限: 修改/删除动态, 修改/删除评论
 * 2.接口: 业务接口系统/后端管理系统
 *  一对一: user -> role
 *  多对多: role -> menu(删除动态/修改动态)
 */
const verifyPermission = async (ctx, next) => {
  console.log("验证权限的middleware~");

  // 1.获取参数 { commentId: '1' }  获取key值commentId
  const [resourceKey] = Object.keys(ctx.params);
  // 解析出表名
  const tableName = resourceKey.replace('Id', '');
  // 在通过表名得到comment_id的值
  // resourceId资源id
  const resourceId = ctx.params[resourceKey];
  const { id } = ctx.user;

  // 2.查询是否具备权限
  try {
    const isPermission = await authService.checkResource(tableName, resourceId, id);
    if (!isPermission) throw new Error();
    await next();
  } catch (err) {
    const error = new Error(errorTypes.UNPERMISSION);
    return ctx.app.emit('error', error, ctx);
  }
}
// // 验证权限 第二种通用  在写路由的时候就传个参数
// const verifyPermission = (tableName) => {
//   return async (ctx, next) => {
//     console.log("验证权限的middleware~");

//     // 1.获取参数
//     const { momentId } = ctx.params;
//     const { id } = ctx.user;

//     // 2.查询是否具备权限
//     try {
//       const isPermission = await authService.checkResource(tableName, momentId, id);
//       if (!isPermission) throw new Error();
//       await next();
//     } catch (err) {
//       const error = new Error(errorTypes.UNPERMISSION);
//       return ctx.app.emit('error', error, ctx);
//     }
//   }
// }

module.exports = {
  verifyLogin,
  verifyAuth,
  verifyPermission,
};
